﻿using CAION2.Properties;
using MenuItem = System.Windows.Controls.MenuItem;

namespace CAION2.ViewModels
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Data;
    using System.IO;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;

    using Classes;
    using Commands;
    using Helpers;
    using Models;
    using Views;

    using FirstFloor.ModernUI.Windows.Controls;

    using MenuItem = MenuItem;

    class StigmaPlaceViewModel : ViewModelBase
    {
        #region Vars

        private BitmapImage _background;
        private double _enhantOpacity;
        private BitmapImage _icon;
        private bool _isEnabled;
        private SolidColorBrush _redBackground;
        private StigmaCardViewModel _stigma;
        private StigmaToolTipViewModel _toolTipData;

        #endregion

        #region Properties

        public BitmapImage Background
        {
            get { return _background; }
            private set
            {
                if (Equals(_background, value)) return;
                _background = value;

                OnPropertyChanged("Background");
            }
        }

        public ObservableCollection<object> ContextMenuItems { get; private set; }

        public DataRow CurrentStigmaRow { get; set; }

        public Double EnhantOpacity
        {
            get { return _enhantOpacity; }
            private set
            {
                if (Equals(_enhantOpacity, value)) return;
                _enhantOpacity = value;

                OnPropertyChanged("EnhantOpacity");
            }
        }

        public BitmapImage Icon
        {
            get { return _icon; }
            private set
            {
                if (Equals(_icon, value)) return;
                _icon = value;

                OnPropertyChanged("Icon");
            }
        }

        public byte Index { get; private set; }

        public bool IsEnabled
        {
            get
            {
                return _isEnabled;
            }
            private set
            {
                _isEnabled = value;
                OnPropertyChanged("IsEnabled");
            }
        }

        public SolidColorBrush RedBackground
        {
            get { return _redBackground; }
            private set
            {
                if (Equals(_redBackground, value)) return;
                _redBackground = value;

                OnPropertyChanged("RedBackground");
            }
        }

        public StigmaCardViewModel Stigma
        {
            get
            {
                return _stigma;
            }
            set
            {
                if (Equals(_stigma, value)) return;
                _stigma = value;
                //this.OnPropertyChanged("Stigma");
            }
        }

        public StigmaToolTipViewModel ToolTipData
        {
            get
            {
                return _toolTipData;
            }
            private set
            {
                if (Equals(_toolTipData, value)) return;
                _toolTipData = value;
                OnPropertyChanged("ToolTipData");
            }
        }

        public List<string> UsualStigmas { private get; set; }

        private string CurrentCharacterClass { get; set; }

        private byte CurrentCharacterLevel { get; set; }

        private bool CurrentCharacterRace { get; set; }

        public bool IsEnhanced { get; set; }
        private byte Level { get; set; }
        #endregion

        #region Commands

        public RelayCommand AddEnhantedStigmaToPlaceCommand { get; private set; }
        
        public RelayCommand<string> ChangeStigmaCommand { get; private set; }

        public RelayCommand DeletePlaceCommand { get; private set; }

        public RelayCommand GetItemForPlaceCommand { get; private set; }
        #endregion

        public StigmaPlaceViewModel()
        {
            WireCommands();
            Stigma = new StigmaCardViewModel();
            UsualStigmas = new List<string>();

            ContextMenuItems = new ObservableCollection<object>
                               {
                                   new MenuItem
                                   {
                                       Header =
                                           Resources
                                           .Manastones_MenuDelete,
                                       Command = DeletePlaceCommand
                                   }
                               };
        }

        public StigmaPlaceViewModel(bool isEnhanted, byte index, StigmaCardViewModel stigma)
        {
            WireCommands();
            Stigma = stigma;
            CurrentStigmaRow = Stigma.GetCurrentStigma();

            IsEnhanced = isEnhanted;
            if (CurrentStigmaRow != null) Level = (byte)CurrentStigmaRow["level"];
            Index = index;

            UsualStigmas = new List<string>();
            ContextMenuItems = null;
            ToolTipData = new StigmaToolTipViewModel(null, null);

            Mediator.Instance.Register(o => SetEnchantOpacity((Tuple<string, string>)o), Messages.SetStigmaPlace);
            EnhantOpacity = 1;
        }

        public StigmaPlaceViewModel(bool isEnhanted, byte level, byte index) : this()
        {
            IsEnhanced = isEnhanted;
            Level = level;
            Index = index;
            IsEnabled = false;
            ToolTipData = new StigmaToolTipViewModel(IsEnhanced ? Resources.Stigma_EnchantStigma : Resources.Stigma_UsualStigma, null);

            SetBackground();
        }

        public void DeletePlace()
        {
            if (Stigma.GetCurrentStigma() != null)
            {
                Mediator.Instance.NotifyColleagues(Messages.SetStigmaPlace,
                    new Tuple<string, string>("del", Stigma.GetCurrentStigma()["skill_group_name"].ToString()));
            }

            Stigma = new StigmaCardViewModel();
            CurrentStigmaRow = null;
            RedBackground = new SolidColorBrush(Colors.Transparent);
            Update();

            int[] sums = { Index, 0, 0 };
            Mediator.Instance.NotifyColleagues(Messages.StigmaSumsSend, sums);
        }

        private void EnhantedUpdate()
        {
            if (string.IsNullOrEmpty(Stigma.CurrentStigmaKey))
            {
                Icon = null;
                IsEnabled = false;
                ToolTipData.Translate = null;
                ToolTipData.CurrentStigmaRow = null;
            }
            else
            {
                Icon = File.Exists(DataModel.IconsDirectory + Stigma.GetCurrentStigma()["skillicon_name"] + ".png")
                    ? new BitmapImage(new Uri(DataModel.IconsDirectory + Stigma.GetCurrentStigma()["skillicon_name"] + ".png", UriKind.RelativeOrAbsolute))
                    : new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/IconSlot.png", UriKind.Absolute));
                ToolTipData.Translate = null;
                ToolTipData.CurrentStigmaRow = Stigma.GetCurrentStigma();
                IsEnabled = true;
            }

            SetBackground();
        }

        public void SetEnabled(string currentCharacterClass, byte currentCharacterLevel, bool currentCharacterRace)
        {
            CurrentCharacterClass = currentCharacterClass;
            CurrentCharacterLevel = currentCharacterLevel;
            CurrentCharacterRace = currentCharacterRace;

            IsEnabled = Level <= CurrentCharacterLevel;
            if (!_isEnabled && !string.IsNullOrEmpty(Stigma.CurrentStigmaKey))
            {
                DeletePlace();
            }
            else
            {
                Update();
            }
        }

        public void SetRedBackground(byte newLevel, string newClass)
        {
            if (!_isEnabled) return;

            bool[] isOn = new bool[2];
            isOn[0] = false;
            isOn[1] = false;

            if (!string.IsNullOrEmpty(Stigma.CurrentStigmaKey))
            {
                if (newLevel < Convert.ToByte(Stigma.GetCurrentStigma()["level"])) isOn[0] = true;
                isOn[1] = Convert.ToByte(Stigma.GetCurrentStigma()[ClassGameClass.GetGameClassFieldNameFromClassName(newClass)]) == 0;
            }

            RedBackground = isOn[0] || isOn[1] ? new SolidColorBrush(ClassConfiguration.RedColor) : new SolidColorBrush(Colors.Transparent);
        }

        public void Update()
        {
            if (string.IsNullOrEmpty(Stigma.CurrentStigmaKey))
            {
                DeletePlaceCommand.IsEnabled = false;
                ToolTipData.Translate = IsEnhanced ? Resources.Stigma_EnchantStigma : Resources.Stigma_UsualStigma;
                ToolTipData.CurrentStigmaRow = null;
                Icon = null;
            }
            else
            {
                Icon = File.Exists(DataModel.IconsDirectory + Stigma.GetCurrentStigma()["skillicon_name"] + ".png")
                    ? new BitmapImage(new Uri(DataModel.IconsDirectory + Stigma.GetCurrentStigma()["skillicon_name"] + ".png", UriKind.RelativeOrAbsolute))
                    : new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/IconSlot.png", UriKind.Absolute));

                DeletePlaceCommand.IsEnabled = true;
                ToolTipData.Translate = null;
                ToolTipData.CurrentStigmaRow = Stigma.GetCurrentStigma();
            }

            SetBackground();

            int crystalShard = 0;
            if (Stigma.CurrentStigmaKey != null && Stigma.GetCurrentStigma()["require_shard"] != DBNull.Value)
                crystalShard = (int)Stigma.GetCurrentStigma()["require_shard"];
            int abyssPoint = 0;
            if (Stigma.CurrentStigmaKey != null && Stigma.GetCurrentStigma()["abyss_point"] != DBNull.Value)
                abyssPoint = (int)Stigma.GetCurrentStigma()["abyss_point"];

            int[] sums = { Index, crystalShard, abyssPoint };
            Mediator.Instance.NotifyColleagues(Messages.StigmaSumsSend, sums);

            UpdateContextMenu(string.IsNullOrEmpty(Stigma.CurrentStigmaKey));
        }

        private void ChangeStigmaInGroup(string stigmaName)
        {
            Stigma.CurrentStigmaKey = stigmaName;
            CurrentStigmaRow = Stigma.GetCurrentStigma();
            Update();
            SetRedBackground(CurrentCharacterLevel, CurrentCharacterClass);
        }

        private void SelectNewItem()
        {
            UiServices.SetBusyState();

            SelectStigmaPage ss = new SelectStigmaPage();
            SelectStigmaDialogViewModel ssvm = (SelectStigmaDialogViewModel)ss.DataContext;

            ModernDialog md = new ModernDialog { Content = ss, Title = Resources.Stigma_SelectStigmaDialogTitle };

            ssvm.CurrentCharacterClass = CurrentCharacterClass;
            ssvm.CurrentCharacterLevel = CurrentCharacterLevel;
            ssvm.CurrentCharacterRace = CurrentCharacterRace;

            ssvm.LoadStigmas(UsualStigmas);
            if (!string.IsNullOrEmpty(Stigma.CurrentStigmaKey)) ssvm.SetSelectedStigma(Stigma.Stigmas[Stigma.CurrentStigmaKey]["name"].ToString());

            md.MaxWidth = 1500;

            md.Buttons = new[] { md.OkButton, md.CancelButton };
            md.ShowDialog();

            if (md.GetDialogResult == MessageBoxResult.Cancel || ssvm.SelectedStigma == null) return;

            Stigma = new StigmaCardViewModel(ssvm.SelectedStigma, CurrentCharacterLevel, Index, CurrentCharacterRace);
            CurrentStigmaRow = Stigma.GetCurrentStigma();
            Update();

            Mediator.Instance.NotifyColleagues(Messages.SetStigmaPlace,
               new Tuple<string, string>("add", Stigma.GetCurrentStigma()["skill_group_name"].ToString()));
        }

        private void SetBackground()
        {
            if (IsEnabled)
            {
                if (Stigma != null && !string.IsNullOrEmpty(Stigma.CurrentStigmaKey))
                {
                    Background = IsEnhanced
                                     ? new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/StigmaEnchant_Set.png", UriKind.Absolute))
                                     : new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Stigma_Set.png", UriKind.Absolute));
                }
                else
                {
                    Background = IsEnhanced
                                     ? new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/StigmaEnchant_Open.png", UriKind.Absolute))
                                     : new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Stigma_Open.png", UriKind.Absolute));
                }
            }
            else
            {
                Background = new BitmapImage();
            }
        }

        private void SetEnchantOpacity(Tuple<string, string> groupInfo)
        {
            if (Stigma.GetCurrentStigma()["skill_group_name"].ToString() != groupInfo.Item2) return;
            switch (groupInfo.Item1)
            {
                case "add":
                    EnhantOpacity = 0.15f;
                    break;
                case "del":
                    EnhantOpacity = 1.0f;
                    break;
            }
        }

        private void UpdateContextMenu(bool isDeleteOnly)
        {
            ContextMenuItems = new ObservableCollection<object>();

            if (!isDeleteOnly && Stigma.Stigmas.Count > 1)
            {
                foreach (KeyValuePair<string, DataRow> pair in Stigma.Stigmas.Where(pair => pair.Key != Stigma.CurrentStigmaKey
                    && (byte)pair.Value["level"] <= CurrentCharacterLevel))
                {
                    ContextMenuItems.Add(new MenuItem
                    {
                        Header = string.Format("{0} - {1}", pair.Value["Level"], pair.Value["Translate"]),
                        Command = ChangeStigmaCommand,
                        CommandParameter = pair.Value["name"]
                    });
                }

                ContextMenuItems.Add(new Separator());
            }

            ContextMenuItems.Add(new MenuItem { Header = Resources.Manastones_MenuDelete, Command = DeletePlaceCommand });
            OnPropertyChanged("ContextMenuItems");
        }

        private void WireCommands()
        {
            GetItemForPlaceCommand = new RelayCommand(SelectNewItem) { IsEnabled = true };
            DeletePlaceCommand = new RelayCommand(DeletePlace) { IsEnabled = false };
            ChangeStigmaCommand = new RelayCommand<string>(ChangeStigmaInGroup) { IsEnabled = true };
            AddEnhantedStigmaToPlaceCommand = new RelayCommand(SendNewItemFromEnhanted) { IsEnabled = true };
        }

        public void SetEnhantedPlace(Dictionary<string, DataRow> stigmas, byte currentLevel, string currentClass, bool currentRace)
        {
            CurrentCharacterLevel = currentLevel;
            CurrentCharacterClass = currentClass;
            CurrentCharacterRace = currentRace;

            KeyValuePair<string, DataRow> currentStigma = stigmas.LastOrDefault(s => (byte)s.Value["level"] <= CurrentCharacterLevel);
            if (currentStigma.Key == null)
            {
                currentStigma = stigmas.FirstOrDefault();
            }

            Stigma = new StigmaCardViewModel(stigmas,
                                             CurrentCharacterLevel,
                                             Index,
                                             currentStigma.Key);
            
            CurrentStigmaRow = Stigma.GetCurrentStigma();
            Level = (byte)CurrentStigmaRow["level"];
            
            EnhantedUpdate();
            SetRedBackground(CurrentCharacterLevel, CurrentCharacterClass);
        }
        
        private void SendNewItemFromEnhanted()
        {
            if (Math.Abs(EnhantOpacity - 1) > 0) return;
            Mediator.Instance.NotifyColleagues(Messages.EnhantedStigmaSend, new Tuple<bool, StigmaCardViewModel>(IsEnhanced, Stigma));
        }
    }
}
